package com.itita.ww2.game.user;

import java.util.Collection;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.itita.ww2.core.WW2Exception;
import com.itita.ww2.data.MissionConfig;
import com.itita.ww2.enums.WW2ExceptionCode;
import com.itita.ww2.game.user.UserRewardDispatch.RewardType;
import com.itita.ww2.model.CodeType;
import com.itita.ww2.model.MissionData;
import com.itita.ww2.model.interfaces.IModelUpdater;
import com.itita.ww2.model.user.UserProfile;
import com.itita.ww2.redis.RedisUtil;
import com.itita.ww2.redis.cache.Table;
import com.itita.ww2.utils.DataUtil;
import com.itita.ww2.utils.MathUtil;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSDataType;
import com.smartfoxserver.v2.entities.data.SFSDataWrapper;
import com.smartfoxserver.v2.entities.data.SFSObject;

/**
 * 玩家关卡(任务)管理器
 * @author NorthLan
 *
 */
public class UserMissionManager implements IModelUpdater {
	private static final Logger logger = LoggerFactory.getLogger(UserMissionManager.class);
	// 
	private int uid;
	private UserProfile userProfile;
	private Table table;

	public UserMissionManager(UserProfile userProfile) {
		this.userProfile = userProfile;
		this.uid = this.userProfile.getUid();
		this.table = UserService.getInstance().getCacheMissionDataTable();
	}

	/**
	 * 任务完成
	 */
	public ISFSObject missionComplete(String missionId, Collection<String> armyKeys) {
		Map<String, MissionData> data = getAllMissionData();
		boolean isFirst = !isCompleted(missionId, data);

		ISFSObject params = SFSObject.newInstance();
		params.putBool("first", isFirst);
		params.putUtfString("missionId", missionId);
		if (armyKeys != null) {
			params.putUtfStringArray("armyKeys", armyKeys);
		}

		ISFSObject backObj = userProfile.getRewardManager().onReward(RewardType.MISSION_COMPLETE, params);
		backObj.putBool("isFirst", isFirst);
		// log
		if (isFirst) {
			data.put(missionId, new MissionData(missionId));
		} else {
			data.get(missionId).addComplete(); // 添加通关
		}
		update(data);
		return backObj;
	}

	/**
	 * 扫荡
	 */
	public ISFSObject rush(String missionId) throws WW2Exception {
		Map<String, MissionData> data = getAllMissionData();
		if (!isCompleted(missionId, data)) {
			logger.error("user: {}:{} hasn't complete this mission, can't rush now!", userProfile.getNickname(),
					userProfile.getUid());
			return null;
		}

		//		ISFSObject params = SFSObject.newInstance();
		//		params.putUtfString("missionId", missionId);
		//		ISFSObject backObj = ItemService.useItemProp(userProfile, params, ItemPropType.FUNCTION,
		//				P1FunctionType.RUSH_COIN.ordinal());

		// 体力不够 不给使用
		if (!userProfile.getUserInfo().isFatigueEnough(missionId)) {
			throw new WW2Exception(WW2ExceptionCode.USER_FATIGUE_NOT_ENOUGH);
		}
		ISFSObject ref = SFSObject.newInstance();
		// 资源奖励
		UserResource resManager = userProfile.getResManager();
		ISFSObject rewardObj = MissionConfig.getRewardComplete(missionId);
		ISFSObject resObj = SFSObject.newInstance();
		for (String key : rewardObj.getKeys()) {
			CodeType type = CodeType.codeValueOf(key);
			if (type == CodeType.RESOURCE) {
				resManager.operResWithCheck(key, rewardObj.getInt(key));
				resObj.putInt(key, rewardObj.getInt(key));
			}
		}
		resManager.update();
		resManager.sync();
		ref.putSFSObject("res", resObj);

		// 道具奖励
		UserInventoryManager inventoryManager = userProfile.getInventory();
		ISFSObject itemObj = SFSObject.newInstance();
		// 叠加
		ISFSObject rushRewardObj = MissionConfig.getRewardRush(missionId);
		for (String key : rushRewardObj.getKeys()) {
			inventoryManager.addItem(key, rushRewardObj.getInt(key));
			itemObj.putInt(key, rushRewardObj.getInt(key));
		}
		// 正常
		ISFSObject completeRewardObj = MissionConfig.getRewardComplete(missionId);
		for (String key : completeRewardObj.getKeys()) {
			CodeType codeType = CodeType.codeValueOf(key);
			if (codeType != CodeType.ITEM) {
				continue;
			}
			int count = 0;
			SFSDataWrapper item = completeRewardObj.get(key);
			if (item.getTypeId() == SFSDataType.SFS_OBJECT) {
				// 数量随机
				ISFSObject obj = (ISFSObject) item.getObject();
				int min = obj.getInt("min");
				int max = obj.getInt("max");
				count = MathUtil.RandomInt(min, max);
			} else if (item.getTypeId() == SFSDataType.INT) {
				count = (int) item.getObject();
			}
			// 数量0个就不加了哈哈
			if (count == 0) {
				continue;
			}
			inventoryManager.addItem(key, count);
			itemObj.putInt(key, count);
		}
		// 扣除体力
		userProfile.getUserInfo().fatigueCostByMission(missionId);
		// 指挥官经验+
		userProfile.getUserInfo().growExpByMission(missionId);
		ref.putSFSObject("item", itemObj);

		// log
		data.get(missionId).addRush();
		update(data);
		return ref;
	}

	//////////////////////////////////////////////////
	public Map<String, MissionData> getAllMissionData() {
		return DataUtil.json2ObjBean(table.getValue(RedisUtil.genericKey(uid), "data"),
				new TypeToken<Map<String, MissionData>>() {
				});
	}

	public MissionData getMissionDataById(String missionId) {
		return this.getAllMissionData().get(missionId);
	}

	/**
	 * 是否通关过
	 */
	private boolean isCompleted(String missionId, Map<String, MissionData> data) {
		return data.containsKey(missionId);
	}

	/**
	 * 是否首次(外部访问)
	 */
	public boolean isFirst(String missionId) {
		return !isCompleted(missionId, getAllMissionData());
	}
	//////////////////////////////////////////////////

	@Override
	public <T> void update(T t) {
		// t -> Map
		// table.setValue(RedisUtil.genericKey(uid), "uid", uid);
		table.setValue(RedisUtil.genericKey(uid), "data", new GsonBuilder().create().toJson(t));
	}
}
